package cn.rengy.web.framework.wxmp.message;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.rengy.tool.core.GenericTokenParser;
import cn.rengy.tool.core.TokenHandler;
import cn.rengy.tpa.wxmp.message.TemplateMsg;
import cn.rengy.tpa.wxmp.message.template.TemplateMsgBody;
import cn.rengy.tpa.wxmp.message.template.TemplateMsgData;
import cn.rengy.tpa.wxmp.token.AccessToken;
import cn.rengy.web.framework.cache.CacheService;
import cn.rengy.web.framework.constants.Constants;
import cn.rengy.web.framework.sql.DbService;
import cn.rengy.web.framework.wxmp.message.entity.TemplateData;
import cn.rengy.web.framework.wxmp.message.entity.TemplateInstance;
import cn.rengy.web.framework.wxmp.message.entity.TemplateMessage;
import cn.rengy.web.framework.wxmp.token.AccessTokenCacheService;
/**
 * 模板消息
 * @author rengy
 *
 */
@Service
public class TemplateMessageService {
	@Autowired
	private DbService dbService;
	@Autowired
	private AccessTokenCacheService accessTokenCacheService;
	@Autowired
	private CacheService cacheService;
	private static Logger logger = LoggerFactory.getLogger(TemplateMessageService.class);
	/**
	 * 发送模板消息
	 */
	public void sendTemplateMessage(TemplateMessage templateMessage) {
		String appid=templateMessage.getAppid();
		String template_instance_id=templateMessage.getTemplate_instance_id();
		Map<String,String> dataMap=templateMessage.getData();
		List<String> openidList=templateMessage.getOpenidList();
		String url=templateMessage.getUrl();
				
		TemplateInstance templateInstance=getTemplateInstance(template_instance_id);
		String template_id_short=templateInstance.getTemplate_id_short();
		String template_id=getTemplateId(appid,template_id_short);
		List<TemplateData> dataList=templateInstance.getDataList();
		
		TemplateMsgBody templateMsgBody = new TemplateMsgBody();
		templateMsgBody.setTemplateId(template_id);
		templateMsgBody.setColor(templateInstance.getColor());
		templateMsgBody.setUrl(url);
		
		GenericTokenParser parser=new GenericTokenParser("#","#",new TokenHandler() {
			@Override
			public String handleToken(String content) {
				return dataMap.get(content);
			}
			
		});
		List<TemplateMsgData> templateMsgDataList = new ArrayList<TemplateMsgData>();
		for(TemplateData td:dataList) {
			TemplateMsgData templateMsgData = new TemplateMsgData();
			templateMsgData.setColor(td.getColor());
			templateMsgData.setName(td.getKey());
			templateMsgData.setValue(parser.parse(td.getValue()));
			templateMsgDataList.add(templateMsgData);
		}
		templateMsgBody.setData(templateMsgDataList);
		AccessToken accessToken = accessTokenCacheService.getAccessToken(appid);
		if(openidList!=null) {
			List<String> openidListWithoutDuplicates = openidList.stream().distinct().collect(Collectors.toList());
			for(String openid:openidListWithoutDuplicates) {
				templateMsgBody.setTouser(openid);
				try {
					TemplateMsg.send(accessToken,templateMsgBody);
				}catch(Exception e) {
					logger.error(ExceptionUtil.stacktraceToString(e,10000));
				}
				
			}
		}
	}
	
	public TemplateInstance getTemplateInstance(String template_instance_id) {
		return cacheService.getCache(Constants.KEY_TemplateInstance, template_instance_id, new Callable<TemplateInstance>() {
	        @Override
	        public TemplateInstance call() throws Exception {
	        	TemplateInstance templateInstance=dbService.queryForBean("select_get_wx_msg_template_instance", TemplateInstance.class, template_instance_id);
	    		List<TemplateData> dataList=dbService.queryForBeanList("select_get_wx_msg_template_data", TemplateData.class, template_instance_id);
	    		templateInstance.setDataList(dataList);
	    		return templateInstance;
	        }
	    });
		
	}
	public String getTemplateId(String appid,String template_id_short) {
		StringBuilder sb=new StringBuilder(appid).append(Constants.redisDelimiter).append(template_id_short);
		String key=sb.toString();
		return cacheService.getCache(Constants.wxMsgTemplateIdCache, key, new Callable<String>() {
	        @Override
	        public String call() throws Exception {
	        	String template_id=null;
	    		template_id = dbService.querySingleColumn("select_template_id_by_code", String.class, template_id_short,appid);
	    		if(StringUtils.isBlank(template_id)){
	    			//1.获取
	    			AccessToken accessToken=accessTokenCacheService.getAccessToken(appid);
	    			template_id = TemplateMsg.getTemplateId(accessToken,template_id_short);
	    			//2.新增到数据库
	    			dbService.update("insert_template_msg_instance", template_id,template_id_short,appid);
	    		}
	    		return template_id;
	        }
	    });
		
		
	}
}
